using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.ServiceProcess;
using System.Text;

using GuerillaProgrammer.Components.Logging;
using GuerillaProgrammer.Components.GPThreadPool;
using GuerillaProgrammer.FileProcessor;
using GuerillaProgrammer.FileProcessor.Settings;

namespace GuerllaProgrammer.FileProcessor.Service
{
    partial class FileProcessorService : ServiceBase,  PollingCallback 
    {
        #region Private member fields
        private Configuration _Configuration;
        private PollingController _PC;
        private bool _KeepGoing;
        private DirectoryProcessorController _DirectoryController;
        private FileProcessingController _FileController;
        #endregion

        #region Constructors and cleanup methods
        public FileProcessorService()
        {
                        
            InitializeComponent();

            bool debug = false;
            bool.TryParse(System.Configuration.ConfigurationManager.AppSettings["ServiceDebug"], out debug);
            if (true == debug)
            {
                System.Diagnostics.Debug.WriteLine(string.Format("Current directory: {0}", AppDomain.CurrentDomain.BaseDirectory));
                System.Diagnostics.Debugger.Break();
            }

            _Configuration = GetConfiguration();
            _FileController = new FileProcessingController(_Configuration);
            _DirectoryController = new DirectoryProcessorController(_Configuration, _FileController);

        }
        #endregion

        #region Private implementation methods
        private Configuration GetConfiguration()
        {
            Logger.LogEnter();
            string configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, System.Configuration.ConfigurationManager.AppSettings["ConfigFilePath"]);
            System.Diagnostics.Debug.WriteLine(string.Format("configuration path: {0}",configPath));
            if (false == File.Exists(configPath))
            {
                Logger.LogWarning("Configuration", "The config file is missing. We're done.");
                throw new FileNotFoundException("Configuration file is missing!");
            }
            Logger.LogLeave();
            return ConfigurationManager.ReadConfiguration(configPath);

        }
        #endregion

        #region Public interface
        protected override void OnStart(string[] args)
        {
            Logger.LogEnter();
            int pollingTime = 5;
            int.TryParse(_Configuration.Services.PollingTime, out pollingTime);
            
            _KeepGoing = true;

            _PC = new PollingController(pollingTime, (PollingCallback)this);
            _PC.StartPollingInterval();
            Logger.LogLeave();
        }
        protected override void OnStop()
        {
            Logger.LogEnter();
            Logger.LogInfo("OnStop", "Stopping the processor");
            _KeepGoing = false;
            Logger.LogLeave();
        }
        public void Execute()
        {
            Logger.LogEnter();
            string message = string.Format("Timer - {0}", DateTime.Now.ToString("hh:mm:ss"));

            Logger.LogInfo("Processor", "Scanning directories for work items");
            _DirectoryController.ProcessDirectories();

            if (true == _KeepGoing)
            {
                Logger.LogInfo("Polling timer", "Starting timer.");
                _PC.StartPollingInterval();
            }
            else
            {
                Logger.LogInfo("Polling timer", "Stop has been issued");
            }
            Logger.LogLeave();
        }
        #endregion
    }
}
